#ifndef VECTOR3FP_H_INCLUDED
#define VECTOR3FP_H_INCLUDED

#include "FPmath.h"

struct Quaternion {
    Fixed w,x,y,z;
};


struct Vector3FP {

  Fixed x,y,z;

  Vector3FP() : x(0),y(0),z(0) {}
  Vector3FP(const Fixed& X, const Fixed& Y, const Fixed& Z) : x(X), y(Y), z(Z) {}

  Vector3FP& operator =( const Vector3FP& p) {x=p.x; y=p.y; z=p.z; return *this;}

  Vector3FP operator +(const Vector3FP& p) const {return Vector3FP(x+p.x,y+p.y,z+p.z);}
  Vector3FP& operator +=(Vector3FP p) {*this = *this + p; return *this;}

  Vector3FP operator -(const Vector3FP& p) const {return Vector3FP(x-p.x,y-p.y,z-p.z);}
  Vector3FP& operator -=(Vector3FP p) {*this = *this - p; return *this;}

  Vector3FP operator *(const Fixed& s) const {return Vector3FP(x*s,y*s,z*s);}
  Vector3FP& operator *=(Fixed s) {*this = *this * s; return *this;}

  Vector3FP operator /(const Fixed& s) const {return Vector3FP(x/s,y/s,z/s);}
  Vector3FP& operator /=(Fixed s) {*this = *this / s; return *this;}

  Fixed length() const { return FPmath::sqrt(lengthSq()); }
  Fixed lengthSq() const { return (x * x) + (y * y) + (z * z); }

  Fixed dotProduct(const Vector3FP& p) const {return Fixed(x*p.x + y*p.y + z*p.z);}

  Vector3FP crossProduct(const Vector3FP& p) const { return Vector3FP(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x); }

  Vector3FP& normalize() { Fixed l=length(); return l==0?(*this):(*this/=l); }

};

extern inline Vector3FP operator *(const Fixed& x, const Vector3FP& p) { return p*x; }

#endif // Vector3FP_H_INCLUDED
